package com.heima.account.handler;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baidu.aip.util.Base64Util;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.heima.commons.enums.BusinessErrors;
import com.heima.commons.exception.BusinessRuntimeException;
import com.heima.modules.po.VehiclePO;
import okhttp3.*;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;

@Component
public class AiHelper {
    @Value("${baidu.apikey}")
    private String API_KEY;
    @Value("${baidu.secretkey}")
    private String SECRET_KEY;

    private final static Logger logger = LoggerFactory.getLogger(AiHelper.class);

    final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();


    public static void main(String []args) throws IOException {
        String code = new AiHelper().getLicense(null);
        System.out.println(code);
    }

    /*

    图像识别，获取车牌信息
    文档（行驶证识别）：https://cloud.baidu.com/doc/OCR/s/yk3h7y3ks
    文档（车牌识别）：https://cloud.baidu.com/doc/OCR/s/ck3h7y191
    获取车辆照片url
    将url下载到某个临时文件夹
    将文件编码为base64
    调百度AI接口，返回对应信息
    对比：行驶证车牌 和 车辆车牌是否一致
    如果一致，设置车牌信息，认证通过，身份变更为车主

    简化版业务流程（至少完成）：识别车辆车牌号即可
    API
        id:6472107
        API KEY:nsmg1gAdJ9QUvfexzwLNZl6k
        Secret KEY:jpcVGkjmPph8N1bRqzMAFtPqqbhl8W8q
        "access_token": "24.c4a6796184efef88d51c244caf012f7b.2592000.1742720278.282335-117658992",
    * */
    public String getLicense(VehiclePO vehiclePO) throws IOException {
        //TODO:任务2.1-车辆信息验证代码编写-2day
        //1.获取车辆照片url和行驶证url
        String carUrl = vehiclePO.getCarFrontPhoto();
        String licenseUrl=vehiclePO.getCarBackPhoto();
        //2.下载车辆照片,返回文件名字
        String carFileName = downloadFileFromUrl(carUrl,"D:\\IdeaProjects\\1");
        //3.下载行驶证照片
        String lisenseUrlName=downloadFileFromUrl(licenseUrl,"D:\\IdeaProjects\\2");
        //4.调用百度AI接口，result的是API请求返回的结果
        String reslut1=licensePlate(carFileName);
        //5.调用百度接口，返回驾驶证照片
        String reslut2=vehicleLicense(lisenseUrlName);
        //6.对比：行驶证车牌 和 车辆车牌是否一致
        String plateForCar = getPlateForCar(reslut1);//车牌
        String plateForLicense=getPlateForLicense(reslut2);//行驶证车牌
        if (plateForLicense.equals(plateForCar)) {
            return reslut1;
        }
        return "00000";
    }
    //根据行驶证照片获取车牌号
    private String getPlateForLicense(String reslut2) {
        JSONObject jsonObject = JSON.parseObject(reslut2);
        System.out.println(jsonObject.getJSONObject("words_result"));
        System.out.println(jsonObject.getString("words"));
        return jsonObject.getJSONObject("words_result")
                .getJSONObject("号牌号码")
                .getString("words");

    }

    //根据车辆照片获取车牌号
    private String getPlateForCar(String json) {
        //将传入的json字符串解析为JSONObject对象
        JSONObject jsonObject = JSON.parseObject(json);
        //从 jsonObject 中获取键名为 "words_result" 的值，该值是一个嵌套的 JSON 对象。
        //getJSONObject 方法用于获取嵌套的 JSON 对象
        //getJSONObject 方法用于获取字符串类型的值
        System.out.println(jsonObject.getJSONObject("words_result"));
        System.out.println(jsonObject.getString("number"));
        return jsonObject.getJSONObject("words_result").
                getString("number");
    }

    /**
     * 把图片url下载到本地folderPath
     * @param url
     * @param folderPath
     * @return
     * @throws IOException
     */
    private String downloadFileFromUrl(String url, String folderPath) throws IOException {
        //检查URL是否为空
        if (url==null || url.isEmpty()){
            throw new IllegalArgumentException("URL can not be null or empty");
        }
        //根据文件路径创建一个文件对象
        File folder = new File(folderPath);
        // 检查文件夹是否存在，如果不存在则创建
        if (!folder.exists()){
            //创建文件夹
            folder.mkdirs();
        }
        //生成文件名,SimpleDateFormat 是 Java 中用于格式化和解析日期的类。它允许将 Date 对象转换为特定格式的字符串，或者将符合特定格式的字符串解析为 Date 对象
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        //new Date()生成现在的时间，SimpleDateFormat可以格式化Date对象
        String timestamp = sdf.format(new Date());
        String fileName = "temp_" + timestamp + ".jpg";
        //文件目录+文件名下载文件
        File tempFile=new File(folder,fileName);
        //下载文件到本地
        FileUtils.copyURLToFile(new URL(url),tempFile);
        //对文件进行Base64编码
        //Base64.getEncoder()：获取一个 Base64.Encoder 实例，用于执行 Base64 编码操作。
        //将字节流文件通过encodeToString编码为Base64文件
        Base64.getEncoder().encodeToString(Files.readAllBytes(tempFile.toPath()));
        return fileName;
    }

    /**
     * 用百度接口返回驾驶证号码
     * @param name
     * @return
     */
    private String vehicleLicense(String name) {
        //向百度API的请求路径发送请求，行驶证
        String url="https://aip.baidubce.com/rest/2.0/ocr/v1/vehicle_license";
        try {
            String filePath="D:\\IdeaProjects\\2\\"+name;//本地文件路径
            // 读取图片文件的字节数据
            // Paths.get(filePath) 将文件路径字符串转换成 Path 对象，Files.readAllBytes() 方法读取整个文件的字节流
            // 返回一个 byte[] 数组，表示文件的内容
            //从本地得到了图片的byte[]数据
            byte[] imgData= Files.readAllBytes(Paths.get(filePath));
            // 将字节数据编码为base64字符串
            // Base64Util.encode(imgData) 将读取的文件字节数组 imgData 编码为 Base64 字符串
            // Base64 编码通常用于传输二进制数据，比如图片文件，因为 Base64 可以把二进制数据转成可打印的 ASCII 字符串
            //从字节流数组得到了图片的Base64编码
            String imgStr= Base64Util.encode(imgData);
            //在发送 HTTP 请求时，特别是在 URL 参数中，任何特殊字符都可能引发问题。
            // 因此，需要使用 URLEncoder.encode() 对参数进行编码，使其变成 URL 安全的格式。
            // imgStr 是你 Base64 编码后的图片数据，经过 URL 编码后，它就可以安全地作为请求的一部分传输给服务器了。
            String imgParam=URLEncoder.encode(imgStr,"UTF-8");
            String param="image="+imgParam;
            String accessToken="24.c4a6796184efef88d51c244caf012f7b.2592000.1742720278.282335-117658992";
            //这里需要引入依赖
            String result= HttpUtil.post(url+"?access_token="+accessToken,param);
            return result;
        }catch (Exception e){
            System.out.println("百度地图AI识别异常"+e.getMessage());e.printStackTrace();
        }
        return null;
    }

    /**
     * 用百度AI接口返回车牌信息
     * @param name
     * @return
     */
    private String licensePlate(String name) {
        //向百度API的请求路径发送请求
        String url="https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate";
        try {
            //本地文件路径
            String filePath="D:\\IdeaProjects\\1\\"+name;
            // 读取图片文件的字节数据
            // Paths.get(filePath) 将文件路径字符串转换成 Path 对象，Files.readAllBytes() 方法读取整个文件的字节流
            // 返回一个 byte[] 数组，表示文件的内容
            //从本地得到了图片的byte[]数据
            byte[] imgData= Files.readAllBytes(Paths.get(filePath));
            // 将字节数据编码为base64字符串
            // Base64Util.encode(imgData) 将读取的文件字节数组 imgData 编码为 Base64 字符串
            // Base64 编码通常用于传输二进制数据，比如图片文件，因为 Base64 可以把二进制数据转成可打印的 ASCII 字符串
            //从字节流数组得到了图片的Base64编码
            String imgStr= Base64Util.encode(imgData);
            //在发送 HTTP 请求时，特别是在 URL 参数中，任何特殊字符都可能引发问题。
            // 因此，需要使用 URLEncoder.encode() 对参数进行编码，使其变成 URL 安全的格式。
            // imgStr 是你 Base64 编码后的图片数据，经过 URL 编码后，它就可以安全地作为请求的一部分传输给服务器了。
            String imgParam=URLEncoder.encode(imgStr,"UTF-8");
            String param="image="+imgParam;
            String accessToken="24.c4a6796184efef88d51c244caf012f7b.2592000.1742720278.282335-117658992";
            //这里需要引入依赖
            String result= HttpUtil.post(url+"?access_token="+accessToken,param);
            return result;

        }catch (Exception e){
            System.out.println("百度地图AI识别异常"+e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

}
